package service.impl.graph;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import model.GraphResult;
import model.GraphSearchCriteria;

import org.apache.commons.lang.time.DateUtils;

import service.impl.Converter;

public class DayCounter {
	private static final int MILLISECONDS_IN_DAY = 1000 * 60 * 60 * 24;

	public static String getAnsweredDayCount(List<GraphResult> graphResults, GraphSearchCriteria criteria) {
		if (Converter.isEmpty(criteria.getCourseCode()) || Converter.isEmpty(criteria.getStudentCode())) {
			return null;
		}
		int answeredDays = getAnsweredDays(graphResults);
		long dateCountInPeriod = getDateCountInPeriod(criteria);
		return answeredDays + "/" + dateCountInPeriod;
	}

	private static int getAnsweredDays(List<GraphResult> graphResults) {
		int answeredDays = 0;
		List<Date> temp = new ArrayList<Date>();
		for (GraphResult graphResult : graphResults) {
			Date truncatedDate = DateUtils.truncate(graphResult.getAnswerTime(), Calendar.DATE);
			if (temp.contains(truncatedDate)) {
				continue;
			}
			temp.add(truncatedDate);
			answeredDays++;
		}
		return answeredDays;
	}

	private static long getDateCountInPeriod(GraphSearchCriteria criteria) {
		Date start = criteria.getPeriodFrom();
		Date end = criteria.getPeriodTo();
		if (start == null || end == null) {
			return 1;
		}
		if (end.before(start)) {
			throw new IllegalArgumentException("The end date must be later than the start date");
		}
		// reset all hours mins and secs to zero on start date
		Calendar startCal = GregorianCalendar.getInstance();
		startCal.setTime(start);
		startCal.set(Calendar.HOUR_OF_DAY, 0);
		startCal.set(Calendar.MINUTE, 0);
		startCal.set(Calendar.SECOND, 0);
		long startTime = startCal.getTimeInMillis();

		// reset all hours mins and secs to zero on end date
		Calendar endCal = GregorianCalendar.getInstance();
		endCal.setTime(end);
		endCal.set(Calendar.HOUR_OF_DAY, 0);
		endCal.set(Calendar.MINUTE, 0);
		endCal.set(Calendar.SECOND, 0);
		long endTime = endCal.getTimeInMillis();

		return (endTime - startTime) / MILLISECONDS_IN_DAY;
	}

}
